home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Information / Digests / CSMP Digest / volume 3 / csmp-digest-v3-064 / doubleCR.1 < prev   
Encoding:
Text File  |  1994-12-08  |  51.7 KB  |  1,464 lines

  1. C.S.M.P. Digest             Sat, 08 Oct 94       Volume 3 : Issue 64
  2.  
  3. Today's Topics:
  4.  
  5.         Help!! argc, argv on Macintosh
  6.         How to Check if drivers are open
  7.         Is it possible to notify another mac?
  8.         Memory moving and Inits
  9.         Self-disposing notification crashes
  10.         [CWWWW] PowerPlant Tour document available
  11.  
  12.  
  13.  
  14. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  15. (pottier@clipper.ens.fr).
  16.  
  17. The digest is a collection of article threads from the internet newsgroup
  18. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  19. regularly and want an archive of the discussions.  If you don't know what a
  20. newsgroup is, you probably don't have access to it.  Ask your systems
  21. administrator(s) for details.  If you don't have access to news, you may
  22. still be able to post messages to the group by using a mail server like
  23. anon.penet.fi (mail help@anon.penet.fi for more information).
  24.  
  25. Each issue of the digest contains one or more sets of articles (called
  26. threads), with each set corresponding to a 'discussion' of a particular
  27. subject.  The articles are not edited; all articles included in this digest
  28. are in their original posted form (as received by our news server at
  29. nef.ens.fr).  Article threads are not added to the digest until the last
  30. article added to the thread is at least two weeks old (this is to ensure that
  31. the thread is dead before adding it to the digest).  Article threads that
  32. consist of only one message are generally not included in the digest.
  33.  
  34. The digest is officially distributed by two means, by email and ftp.
  35.  
  36. If you want to receive the digest by mail, send email to listserv@ens.fr
  37. with no subject and one of the following commands as body:
  38.     help                        Sends you a summary of commands
  39.     subscribe csmp-digest Your Name    Adds you to the mailing list
  40.     signoff csmp-digest            Removes you from the list
  41. Once you have subscribed, you will automatically receive each new
  42. issue as it is created.
  43.  
  44. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  45. Questions related to the ftp site should be directed to
  46. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  47. digest are available there.
  48.  
  49. Also, the digests are available to WAIS users.  To search back issues
  50. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  51. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  52.  
  53.  
  54. -------------------------------------------------------
  55.  
  56. >From victor chong <victorc@sleepy.cc.utexas.edu>
  57. Subject: Help!! argc, argv on Macintosh
  58. Date: 22 Sep 1994 21:19:15 GMT
  59. Organization: UT Austin
  60.  
  61. Hi,
  62.     I was wondering if someone could enlighten me concerning
  63. the usage of argv and argc when programming on the Macintosh.
  64. I'm using Symantec C++.
  65.     Does the Mac allows this kind of communication with the
  66. OS or is there another method.
  67.     Any kind of help will be much welcome.
  68.     Thank you very much.
  69.     
  70.     
  71.     
  72.     
  73. victor
  74.  
  75. victorc@sleepy.cc.utexas.edu
  76.  
  77. +++++++++++++++++++++++++++
  78.  
  79. >From Eric.M.Kidd@dartmouth.edu (Eric M. Kidd)
  80. Date: 23 Sep 1994 00:11:36 GMT
  81. Organization: Dartmouth College, Hanover, NH
  82.  
  83. argc and argv do not work at all on any normal mac setup. Sorry.
  84.  
  85. The following program fragment gives an idea of how to get the
  86. old-fashioned app params (files to open or print). If you want to do
  87. anything more complicated, you'll need to use Apple Events.
  88.  
  89. /* openingFiles( )
  90. **
  91. ** Determine if we have parameters. The old-style app parameters are
  92. used for
  93. ** the sake of SPEED. Apple Events are too slow, and I only have
  94. partial docs.
  95. ** Help in acquiring copies of Inside Macintosh always welcome...
  96. */
  97.  
  98. Boolean openingFiles( )
  99. {
  100.     short message;
  101.     short count;
  102.     
  103.     CountAppFiles( &message, &count );
  104.     
  105.     return ( message == 0 && count > 0 );
  106. }
  107.  
  108. /* openFiles( )
  109. **
  110. ** Go through files one by one, processing them along the way.
  111. */
  112.  
  113. void openFiles( )
  114. {
  115.     FSSpec cur;
  116.     AppFile aFile;
  117.     short count;
  118.     short i;
  119.     short mess;
  120.     
  121.     /* I'm not bothering to check for print messages--my app shouldn't get
  122. any */
  123.     CountAppFiles( &mess, &count );
  124.     
  125.     for ( i = 1; i <= count; i++ )
  126.     {
  127.         /* get file and convert from working dir to FSSpec */
  128.         GetAppFiles( i, &aFile );
  129.         FSMakeFSSpec( aFile.vRefNum, 0, aFile.fName, &cur );
  130.         
  131.         processFile( &cur );
  132.     }
  133. }
  134.  
  135. main( )
  136. {
  137.     initMacintosh( );
  138.     initApplication( );
  139.     
  140.     if ( openingFiles( ) )
  141.         openFiles( );
  142.     else
  143.         runApplication( );
  144. }
  145.  
  146. +++++++++++++++++++++++++++
  147.  
  148. >From ruhl@du.edu (ROBERT A. UHL )
  149. Date: Fri, 23 Sep 1994 15:34:11 GMT
  150. Organization: University of Denver
  151.  
  152.   Does anybody have the format of the Handle returned by
  153. GetAppParms()? I don't have IM and have to figure out what the
  154. functions do from the headers. Any help would be appreciated.
  155. -- 
  156. - ------------------------------------
  157. | Bob Uhl | Spectre                  |
  158. | U of D  | Baron Robert von Raetzin |
  159.  
  160. +++++++++++++++++++++++++++
  161.  
  162. >From Carl R. Osterwald <carl_osterwald@nrel.gov>
  163. Date: Fri, 23 Sep 1994 20:48:32 GMT
  164. Organization: National Renewable Energy Laboratory
  165.  
  166. In article <35ssck$m3a@geraldo.cc.utexas.edu> victor chong,
  167. victorc@sleepy.cc.utexas.edu writes:
  168. >    I was wondering if someone could enlighten me concerning
  169. >the usage of argv and argc when programming on the Macintosh.
  170. >I'm using Symantec C++.
  171. >    Does the Mac allows this kind of communication with the
  172. >OS or is there another method.
  173.  
  174. Just use the Symantec console package.  You will need to add one key
  175. element, a ccommand() call, before you access argv/argc.  This puts up a
  176. dialog box that allows you to type in the command line parameters. 
  177. ccommand() was documented in the Think C 5 manuals, in 6 and 7 it is
  178. online inside the free version of Think Reference (I have not verified
  179. this personally).
  180.  
  181. For disk I/O be sure to check the c.s.m.p PD programming FAQ compiled by
  182. Jon Watte.
  183.  
  184. +++++++++++++++++++++++++++
  185.  
  186. >From rrk@rahul.net (Bob R. Kenyon)
  187. Date: Sat, 24 Sep 1994 05:54:04 GMT
  188. Organization: La Casita de Las Pulgas, San Jose, CA
  189.  
  190. In article <35ssck$m3a@geraldo.cc.utexas.edu>, victor chong
  191. <victorc@sleepy.cc.utexas.edu> wrote:
  192.  
  193. > Hi,
  194. >         I was wondering if someone could enlighten me concerning
  195. > the usage of argv and argc when programming on the Macintosh.
  196. > I'm using Symantec C++.
  197. >         Does the Mac allows this kind of communication with the
  198. > OS or is there another method.
  199. >         Any kind of help will be much welcome.
  200. >         Thank you very much.
  201.  
  202. Yeah, if you look in Think Reference, they talk about a function called
  203. ccommand. When your program starts, it throws up a window that allows you
  204. to redirect input and output, and enter command line arguments. It's
  205. pretty funny actually, but not really "Mac" in behavior.
  206.  
  207. Their code example looks like this:
  208.  
  209.  
  210. /* CODE EXAMPLE #1 */
  211. #include <stdio.h>
  212. #include <console.h>
  213.  
  214. main(int argc, char **argv)
  215. {
  216.    int i;
  217.  
  218.    argc = ccommand(&argv);  // this is the command that throws up the window
  219.  
  220.    for (i=0; i<argc; i++)
  221.       printf ("%s ", argv[i]);
  222.  
  223.    printf ("\n");
  224. }
  225.  
  226. I use this technique all the time for my programming classes, because they
  227. haven't covered any kind of windowing stuff. 
  228.  
  229. Hope this helps,
  230. Bob
  231.  
  232. -- 
  233. Bob Kenyon                           | "Pilots take no special joy
  234. Beautiful Downtown San Jose, CA      |  in walking. Pilots like
  235. rrk@rahul.net                        |  flying." -- Neil Armstrong
  236.  
  237. ---------------------------
  238.  
  239. >From ferrari@netaxs.com (Darrell Turner)
  240. Subject: How to Check if drivers are open
  241. Date: Thu, 22 Sep 1994 13:26:38 -0500
  242. Organization: Haha, None here
  243.  
  244. I'm trying to figure out how to check if a driver is open by only
  245. specifying the driver name.  I want it to work for .IPP .AOut, and others
  246. such as ram serail drivers for Hurdlers, etc.
  247.  
  248. My problem is that I can't figure out if it's open without first knowing
  249. the driver unit number.  I was going to walk the UnitTable checking for the
  250. Driver Name  in the DCtlEntry, but I soon discovered that the name is in
  251. there.  This is my current code, and it doesn't work, how can I get this
  252. working?  (The GetNamedResource returns nil, even on stuff I know is in the
  253. System file like .AOut.
  254.  
  255.     function GetNamedDCtlEntry (driverName: str255): DCtlHandle;
  256.         type
  257.             Ptr2Word = ^integer;
  258.             Ptr2Byte = ^byte;
  259.         const
  260.             UnitNtryCnt = $1D2; {[GLOBAL VAR]  count of entries in unit table
  261. [word]}
  262.             RomMapInsert = $B9E;{[GLOBAL VAR] (byte) determines if we should link in
  263. map}
  264.  
  265.         var
  266.             rID: integer;
  267.             rType: ResType;
  268.             hand: handle;
  269.     begin
  270.         SetResLoad(false);
  271.         Ptr2Byte(RomMapInsert)^ := 1;
  272.         hand := GetNamedResource('DRVR', driverName);
  273.         SetResLoad(true);
  274.         GetResInfo(hand, rID, rType, driverName);
  275.         if (rID >= 0) and (rID <= Ptr2Word(UnitNtryCnt)^) then
  276.             GetNamedDCtlEntry := GetDCtlEntry(rID)
  277.         else
  278.             GetNamedDCtlEntry := nil;
  279.     end;
  280.  
  281. begin
  282.     dctl := GetNamedDCtlEntry('.IPP');
  283.     if dCtl = nil then
  284.         Quit(noErr);
  285.     Init;
  286.     repeat
  287.         HandleEvents;
  288.     until (BitTst(@dctl^^.dCtlFlags, 5) or done);
  289.  {...}
  290. end.
  291.  
  292. +++++++++++++++++++++++++++
  293.  
  294. >From resnick@uiuc.edu (Pete Resnick)
  295. Date: Fri, 23 Sep 1994 12:36:16 -0500
  296. Organization: University of Illinois at Urbana-Champaign
  297.  
  298. In article <ferrari-220994132639@slip-55.netaxs.com>, ferrari@netaxs.com (Darrell Turner) wrote:
  299.  
  300. > I'm trying to figure out how to check if a driver is open by only
  301. > specifying the driver name.  I want it to work for .IPP .AOut, and others
  302. > such as ram serail drivers for Hurdlers, etc.
  303. > My problem is that I can't figure out if it's open without first knowing
  304. > the driver unit number.  I was going to walk the UnitTable checking for the
  305. > Driver Name  in the DCtlEntry, but I soon discovered that the name is in
  306. > there.
  307.  
  308. Yes it is. It's in the driver itself, which is pointed to by the DCtl
  309. entry. Here's some code (in C; the conversion to Pascal is pretty easy):
  310.  
  311. /* Structure of the driver resource */
  312. typedef struct {
  313.     short drvrFlags;
  314.     short drvrDelay;
  315.     short drvrEMask;
  316.     short drvrMenu;
  317.     short drvrOpen;
  318.     short drvrPrime;
  319.     short drvrCtl;
  320.     short drvrStatus;
  321.     short drvrClose;
  322.     unsigned char drvrName[];
  323.     unsigned char drvrRoutines[];
  324. } DriverStruct, *DriverPtr, **DriverHandle;
  325.  
  326. #if define(__SYSEQU__)
  327. #define UTABLEBASE  (* (DCtlHandle **)UTableBase)
  328. #define UNITNTRYCNT (* (short *)UnitNtryCnt)
  329. #elif defined(__LOWMEM__)
  330. #define UTABLEBASE  (DCtlHandle *)LMGetUTableBase()
  331. #define UNITNTRYCNT LMGetUnitNtryCnt()
  332. #else
  333. #define UTABLEBASE  UTableBase
  334. #define UNITNTRYCNT UnitNtryCnt
  335. #endif
  336.  
  337. #ifndef dOpened
  338. #   define dOpened      0x0020
  339. #endif /* dOpened */
  340. #ifndef dRAMBased
  341. #   define dRAMBased    0x0040
  342. #endif /* dRAMBased */
  343.  
  344. short GetDrvrRefNum(StringPtr drvrName)
  345. {
  346.   short unitNum;
  347.   DCtlPtr curDCtlPtr, *curDCtlHndl, **UTableEntry;
  348.   DriverPtr curDrvrPtr;
  349.     
  350.   /* Walk through the Unit Table */
  351.   UTableEntry = UTABLEBASE;
  352.   for(unitNum = 0; unitNum < UNITNTRYCNT; ++unitNum) {
  353.     if((curDCtlHndl = *UTableEntry++) != nil) {
  354.             
  355.       curDCtlPtr = *curDCtlHndl;
  356.             
  357.       /* Get the pointer to the driver */
  358.       curDrvrPtr = (DriverPtr)curDCtlPtr->dCtlDriver;
  359.  
  360.       /* If this is a RAM driver, it's a handle. ROM is a pointer */
  361.       if((curDCtlPtr->dCtlFlags & dRAMBased) && (curDrvrPtr != nil))
  362.         curDrvrPtr = *(DriverPtr *)curDrvrPtr;
  363.             
  364.       /* Does the driver name match? */
  365.       if(curDrvrPtr != nil)
  366.         if(EqualString(drvrName, curDrvrPtr->drvrName, false, true))
  367.           return(~unitNum);
  368.     }
  369.   }
  370.   return(0);
  371. }
  372.  
  373. Boolean IsDriverOpen(StringPtr drvrName)
  374. {
  375.   short unitNum;
  376.   DCtlPtr curDCtlPtr, *curDCtlHndl, **UTableEntry;
  377.   DriverPtr curDrvrPtr;
  378.     
  379.   /* Walk through the Unit Table */
  380.   UTableEntry = UTABLEBASE;
  381.   for(unitNum = 0; unitNum < UNITNTRYCNT; ++unitNum) {
  382.     if((curDCtlHndl = *UTableEntry++) != nil) {
  383.             
  384.       curDCtlPtr = *curDCtlHndl;
  385.             
  386.       /* Get the pointer to the driver */
  387.       curDrvrPtr = (DriverPtr)curDCtlPtr->dCtlDriver;
  388.  
  389.       /* If this is a RAM driver, it's a handle. ROM is a pointer */
  390.       if((curDCtlPtr->dCtlFlags & dRAMBased) && (curDrvrPtr != nil))
  391.         curDrvrPtr = *(DriverPtr *)curDrvrPtr;
  392.             
  393.       /* Does the driver name match? */
  394.       if(curDrvrPtr != nil)
  395.         if(EqualString(drvrName, curDrvrPtr->drvrName, false, true))
  396.           return((curDCtlPtr->dCtlFlags & dOpened) != 0);
  397.     }
  398.   }
  399.   return(false);
  400. }
  401.  
  402. Note: There is an omission in the Universal headers LowMem.h because it
  403. does not define LMGetUnitNtryCnt or LMSetUnitNtryCnt. For the 68000
  404. versions, add:
  405.  
  406. #define LMGetUnitNtryCnt() (* (short *) 0x01D2)
  407.  
  408. #define LMSetUnitNtryCnt(UnitNtryCntValue) ((* (short *) 0x01D2) = (UnitNtryCntValue))
  409.  
  410. I don't know what to do about the PowerPC versions.
  411.  
  412. pr
  413. -- 
  414. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  415. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  416. System manager - Cognitive Science Group, Beckman Institute, UIUC
  417. Internet: resnick@uiuc.edu
  418.  
  419. +++++++++++++++++++++++++++
  420.  
  421. >From csuley@netcom.com (Christopher S. Suley)
  422. Date: Sat, 24 Sep 1994 05:58:12 GMT
  423. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  424.  
  425.  
  426. Here's some code I use to find a driver in the unit table.
  427. It's lightly adapted from Pete Resnick's excellent Driver 2.2,
  428. available at sumex and umich and mirrors thereof.
  429. It's in C, but the translation to Pascal should be pretty easy.
  430.  
  431.  
  432. typedef struct
  433. {
  434.   short drvrFlags;
  435.   short drvrDelay;
  436.   short drvrEMask;
  437.   short drvrMenu;
  438.   short drvrOpen;
  439.   short drvrPrime;
  440.   short drvrCtl;
  441.   short drvrStatus;
  442.   short drvrClose;
  443.   unsigned char drvrName[1]; /* actually variable length p-string */
  444. }
  445. DriverStruct, *DriverPtr;
  446.  
  447. short
  448. FindDriver( void )
  449. {
  450.   Str255      drvrName;
  451.   DCtlHandle  hCurDCE;
  452.   DriverPtr   pCurDrvr;
  453.   short       sDrvrNum;
  454.  
  455.   GetIndString( drvrName, krMiscStrings, ksiDriverNameIndex );
  456.  
  457.   for ( sDrvrNum = LMGetUnitNtryCnt() ; sDrvrNum >= 0 ; --sDrvrNum )
  458.   {
  459.     hCurDCE = GetDCtlEntry( ~sDrvrNum );
  460.     if ( hCurDCE )
  461.     {
  462.       pCurDrvr = ( DriverPtr ) (**hCurDCE).dCtlDriver;
  463.  
  464.       if ( ((**hCurDCE).dCtlFlags & dRAMBased) && pCurDrvr )
  465.       {
  466.         pCurDrvr = *( DriverPtr * ) pCurDrvr;
  467.       }
  468.  
  469.       if ( pCurDrvr &&
  470.            EqualString( drvrName, pCurDrvr->drvrName, false, true ) )
  471.       {
  472.         return ~sDrvrNum;
  473.       }
  474.     }
  475.   }
  476.  
  477.   return 0;
  478. }
  479.  
  480.  
  481. -- 
  482. Want some? <slap, thud>                                       csuley@netcom.com
  483. Want some? <slap, thud>                             ChrisSuley@{eworld,aol}.com
  484.  
  485. ---------------------------
  486.  
  487. >From altitude@umich.edu (Alex Tang)
  488. Subject: Is it possible to notify another mac?
  489. Date: 23 Sep 1994 21:09:51 GMT
  490. Organization: University of Michigan
  491.  
  492. Hi folks.  
  493.  
  494. I was wondering if it was possible to pull up a dialog box or alert box on
  495. another mac via either AppleTalk or IP.  
  496.  
  497. Me 'n some friends want to write an app that will (in it's most simple
  498. incarnation) open up an alert box on another mac and give them a piece of
  499. information.  
  500.  
  501. In it's most complicated incarnation, we would really like to be able to
  502. have one mac contact the notification manager on another mac, and run a
  503. program on that mac.
  504.  
  505. This is all presuming we know the AppleTalk node or IP address of the
  506. sending and receiving mac.
  507.  
  508. Thanx
  509. ...alex...
  510.  
  511.  
  512. --
  513.     Alex Tang      |     UM-SNRE   |       UM-ITD/US Consultant II
  514. ALTITUDE@UMICH.EDU |     Student   |    UM-SNRE-NCEET: Systems Admin
  515.   PGP via finger.  | Systems Admin |http://www.snre.umich.edu/users/altitude
  516. This space for rent|Comp.Consut III| An eye for an eye leaves everyone blind.
  517.  
  518. +++++++++++++++++++++++++++
  519.  
  520. >From nick+@pitt.edu ( nick.c )
  521. Date: Fri, 23 Sep 94 20:42:20 GMT
  522. Organization: The Pitt, Chemistry
  523.  
  524. In Article <35vg70$7v6@lastactionhero.rs.itd.umich.edu>, altitude@umich.edu
  525. (Alex Tang) wrote:
  526.  
  527. >I was wondering if it was possible to pull up a dialog box or alert box on
  528. >another mac via either AppleTalk or IP.  
  529. >
  530. >Me 'n some friends want to write an app that will (in it's most simple
  531. >incarnation) open up an alert box on another mac and give them a piece of
  532. >information.  
  533. >
  534. >In it's most complicated incarnation, we would really like to be able to
  535. >have one mac contact the notification manager on another mac, and run a
  536. >program on that mac.
  537.  
  538.  
  539.     Possible and been done.  I remember seeing a notification like
  540.       program on Umich... forget the name... "Broadcast"?.  Dunno.
  541.       Anyway, as I recall you have to have program linking on on the 
  542.       receiving mac, and have to have loaded an extension on the
  543.       receiving mac that takes your message and forwards it to the
  544.       local notification manager.  You could also create an extension
  545.       that sends out apple events, so could launch a local program
  546.       when keyed remotely.  I'd check out NIM:networking for more
  547.       details, luck
  548.  
  549.                                         -- nick
  550.  
  551.  
  552.  
  553.                                     _/   _/  _/  _/_/_/   _/   _/  
  554.      Interet: nick@pitt.edu        _/_/ _/  _/  _/   _/  _/_/_/    
  555.       eWorld: nick                _/ _/_/  _/  _/       _/ _/      
  556.          CIS: 71232,766          _/   _/  _/   _/_/_/  _/   _/     
  557.  
  558.  
  559. +++++++++++++++++++++++++++
  560.  
  561. >From jonasw@lysator.liu.se (Jonas Wallden)
  562. Date: 24 Sep 1994 21:19:28 GMT
  563. Organization: (none)
  564.  
  565. altitude@umich.edu (Alex Tang) writes:
  566.  
  567. >Hi folks.  
  568. >
  569. >I was wondering if it was possible to pull up a dialog box or alert box on
  570. >another mac via either AppleTalk or IP.  
  571. >
  572. >Me 'n some friends want to write an app that will (in it's most simple
  573. >incarnation) open up an alert box on another mac and give them a piece of
  574. >information.  
  575. >
  576. >In it's most complicated incarnation, we would really like to be able to
  577. >have one mac contact the notification manager on another mac, and run a
  578. >program on that mac.
  579. >
  580. >This is all presuming we know the AppleTalk node or IP address of the
  581. >sending and receiving mac.
  582.  
  583. A nice little hack is 'Radiation + Trigger' which can be used to fake
  584. error messages on anoter Mac's screen. Very useful in lab rooms... :-)
  585. It is an INIT that receives messages through the PPC Toolbox and displays
  586. them as Notification Manager alerts.
  587.  
  588. BTW, the default message is 'The radiation shield on your Macintosh has
  589. failed. Please step back 5 feet.' which explains its name... Use with
  590. care on newbies!
  591.  
  592. --
  593. `.`.   Jonas Wallden                    `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  594. `.`.`.   Internet: jonasw@lysator.liu.se  `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  595. `.`.`.`.   AppleLink: sw1369                `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  596.  
  597. ---------------------------
  598.  
  599. >From jlawrie@malibu.sfu.ca (John William Lawrie)
  600. Subject: Memory moving and Inits
  601. Date: 16 Sep 94 17:13:25 GMT
  602. Organization: Simon Fraser University
  603.  
  604. Hi.  I want to have an extension that performs periodic taks.  I have
  605. a skeleton extension that does this already, but the problem is, I
  606. will want to call toolbox routines that will call the memory manager.
  607. Is there a way around this?
  608.  
  609. John@helix.net
  610.  
  611.  
  612. +++++++++++++++++++++++++++
  613.  
  614. >From onyxtech@aol.com (OnyxTech)
  615. Date: 17 Sep 1994 04:26:02 -0400
  616. Organization: America Online, Inc. (1-800-827-6364)
  617.  
  618. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  619. Lawrie) writes:
  620.  
  621. > Hi.  I want to have an extension that performs periodic
  622. > taks.  I have a skeleton extension that does this already,
  623. > but the problem is, I will want to call toolbox routines
  624. > that will call the memory manager. Is there a way around
  625. > this?
  626.  
  627. It's ok to move memory in a trap patch, but It all depends on what you're
  628. using to trigger your extension code?  If you're installing a time manager
  629. or VBL routine, forget trying to move memory during that code because they
  630. can/will be executed during interupt time and moving memory then is a
  631. strict no no.  If you are triggering your extension code off a trap patch,
  632. them make sure it is a trap patch that can move memory.  Then you're ok. 
  633. If you are triggering off a trap patch that isn't documented as moving
  634. memory, you'd better change your code because you'll eventually get in
  635. trouble. And since I'm not sure what you're patching, better make sure
  636. that what your trap patch calls does not lead to what you're patching. 
  637. Re-entrant city unless you handle it correctly.
  638.  
  639. dEVoN
  640.  
  641. +++++++++++++++++++++++++++
  642.  
  643. >From jcornish@netcom.com (Jud Cornish)
  644. Date: Sun, 18 Sep 1994 08:32:34 GMT
  645. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  646.  
  647. To perform periodic tasks that may move/purge memory:
  648.  
  649. A simple solution is to patch a trap (or several) that are known to
  650. move/purge memory and are commonly called.  I did some "OS Profiling" of
  651. my own to identify a set of traps that I could patch that would give
  652. frequent time to such a task.  The other objective was to get time when
  653. apps, the OS or the Toolbox is in a tight loop such as while tracking a
  654. close box.  If you patch any one trap, there will be times when you can go
  655. for quite some time without an opportunity to snag some time.  I shouldn't
  656. go into the details, but with some common sense (and a little time with
  657. macsbug) one can pick a pretty good set of traps.  All this is only
  658. necessary if you have a really critical time based task.  Not critical in
  659. accuracy, but in avoiding long pauses.  All this is necessary because of
  660. the way "multi-tasking" is done on the mac.  Processes are only granted
  661. time when others share it. 
  662.  
  663. Another option would be to install a driver which requested periodic time. 
  664. This is actually harder than just patching _SystemTask, which I believe
  665. would function identically. 
  666.  
  667. Yet another option is to pre-allocate some memory with your INIT, then eat
  668. it up as you need it.  In a sense, depending on the complexity of your
  669. memory use, you can just start filling up a simple buffer with data, or
  670. you could make your own sub memory manager!!! 
  671.  
  672. A hybrid solution is to perform periodic tasks via the time manager, with
  673. accuracy and nearly guaranteed time, then when you fill up your buffer (or
  674. get sufficiently close to it), you set a flag which a _SystemTask patch
  675. can use to know when to grow the buffer.  You would need to temporarily
  676. suspend your use of the buffer while the patch is growing (and probably
  677. moving) it.  This can be done with another flag manipulated just before
  678. and after the SetHandleSize. The periodic task would always make sure this
  679. flag was clear before dereferencing the handle and using the buffer. 
  680.  
  681. I have little idea what your actual needs are but I hope that this
  682. discussion is helpful.  Hopefully, a simple patch will suffice.  As far as
  683. I have seen (68k sys 7.5), the OS still calls _SystemTask periodically. 
  684. If this is indeed the case, it is a good target as other processes will
  685. expect to share time when this happens (usually from a _waitNextEvent
  686. call). 
  687.  
  688. Any comments on my comments would be appreciated.
  689.  
  690. Erik J. Rogers
  691.  
  692. +++++++++++++++++++++++++++
  693.  
  694. >From resnick@uiuc.edu (Pete Resnick)
  695. Date: Sun, 18 Sep 1994 13:00:37 -0500
  696. Organization: University of Illinois at Urbana-Champaign
  697.  
  698. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  699. Lawrie) wrote:
  700.  
  701. > Hi.  I want to have an extension that performs periodic taks.  I have
  702. > a skeleton extension that does this already, but the problem is, I
  703. > will want to call toolbox routines that will call the memory manager.
  704. > Is there a way around this?
  705.  
  706. My personal favorite is to use a Time Manager task to do the periodic
  707. part, and have the completion proc for the Time Manager routine post a
  708. Notification Manager request that has all the fields except nmResp
  709. cleared. In the notification response, you can do whatever you want to do
  710. since it is Memory Manager safe.
  711.  
  712. pr
  713. -- 
  714. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  715. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  716. System manager - Cognitive Science Group, Beckman Institute, UIUC
  717. Internet: resnick@uiuc.edu
  718.  
  719. +++++++++++++++++++++++++++
  720.  
  721. >From Jaeger@fquest.com (Brian Stern)
  722. Date: 19 Sep 1994 05:03:25 GMT
  723. Organization: The University of Texas at Austin, Austin, Texas
  724.  
  725. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  726. Lawrie) wrote:
  727.  
  728. < Hi.  I want to have an extension that performs periodic taks.  I have
  729. < a skeleton extension that does this already, but the problem is, I
  730. < will want to call toolbox routines that will call the memory manager.
  731. < Is there a way around this?
  732. < John@helix.net
  733.  
  734. A jGNEFilter is a simple way to get periodic time and you can move memory
  735. if you need to.  The only problem is that you aren't guaranteed that it
  736. will be called frequently.
  737.  
  738. -- 
  739. Brian  Stern  :-{)}
  740. Jaeger@fquest.com
  741.  
  742. +++++++++++++++++++++++++++
  743.  
  744. >From blob@apple.com (Brian Bechtel)
  745. Date: 24 Sep 1994 14:39:56 -0700
  746. Organization: Apple Computer, Inc., Cupertino, California
  747.  
  748. Jaeger@fquest.com (Brian Stern) writes:
  749.  
  750. >In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  751. >Lawrie) wrote:
  752.  
  753. >< Hi.  I want to have an extension that performs periodic taks.  I have
  754. >< a skeleton extension that does this already, but the problem is, I
  755. >< will want to call toolbox routines that will call the memory manager.
  756. >< Is there a way around this?
  757.  
  758. >A jGNEFilter is a simple way to get periodic time and you can move memory
  759. >if you need to.  The only problem is that you aren't guaranteed that it
  760. >will be called frequently.
  761.  
  762. Even better is a faceless background application.  You can call any
  763. toolbox routine that doesn't provide a user interface. You get time like
  764. any other application.
  765.  
  766. --Brian Bechtel     blob@apple.com     "My opinion, not Apple's"
  767.  
  768. ---------------------------
  769.  
  770. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  771. Subject: Self-disposing notification crashes
  772. Date: 16 Sep 94 16:35:09 +1200
  773. Organization: University of Waikato, Hamilton, New Zealand
  774.  
  775. I'm working on this MPW tool that sends a PostScript stream to a printer via
  776. PAP, and displays whatever the printer sends back. It loads the PDEF 10 code
  777. from the LaserWriter driver (I know, I know, but this is for in-house use,
  778. and I have ways of keeping it working under QuickDraw GX ;-)). However,
  779. I didn't like the PAPStatus call that that library provides, as it's
  780. synchronous, and tends to hang for several seconds if the printer goes away.
  781.  
  782. So I tried implementing my own version of PAPStatus. My version allocates
  783. a temporary block in the heap, which is used to contain the context for the
  784. call, including pointers to the user's data areas. Once the query starts,
  785. everything runs at interrupt time as a sequence of chained completion routines
  786. from then on, except of course for the last bit of code that gets rid of the
  787. temporary block. This code runs as a notification routine, so that it's safe
  788. for it to make Memory Manager calls.
  789.  
  790. The notification code is actually copied into the temporary block, and executes
  791. out of there. I did this as part of a strategy for dealing cleanly with aborting
  792. execution of the tool, though admittedly my handling of this is not complete
  793. as yet.
  794.  
  795. Anyway, this notification routine is very small, and is written in assembler.
  796. Here it is in its entirety:
  797.  
  798.     move.l    4(sp), a0
  799.     _NMRemove
  800.     move.l    NMRec.nmRefCon(a0), a0
  801.     _DisposePtr
  802.     move.l    (sp)+, (sp)
  803.     rts
  804.  
  805. Note that the DisposePtr call is disposing of the block containing the code
  806. (and the notification record) itself! However, I have stepped through this
  807. code with MacsBug, and watched it successfully return from DisposePtr and
  808. execute those last two instructions just fine.
  809.  
  810. Basically, the problem is, my tool tends to crash, but only the second time
  811. it runs. The first time is always fine: I can send a large multi-page print
  812. job to the printer (with lots of status queries throughout), or I can send
  813. a small one-line query, and it will always work. However, the second time I
  814. try invoking my tool, it will crash.
  815.  
  816. I finally narrowed it down to one thing: the DisposePtr call in the
  817. notification routine, above. If I no-op out the dispose call (causing a
  818. resultant accumulation of allocated memory blocks in MPW's heap), I can run the
  819. tool multiple times just fine.
  820.  
  821. Anybody got any ideas as to why this can't work?
  822.  
  823. Thanks for any help.
  824.  
  825. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  826. Info & Tech Services Division              fax: +64-7-838-4066
  827. University of Waikato            electric mail: ldo@waikato.ac.nz
  828. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  829.  
  830. +++++++++++++++++++++++++++
  831.  
  832. >From pottier@fregate.ens.fr (Francois Pottier)
  833. Date: 16 Sep 1994 11:28:28 GMT
  834. Organization: Ecole Normale Superieure, PARIS, France
  835.  
  836. In article <1994Sep16.163509.33240@waikato.ac.nz>,
  837. Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
  838. >
  839. >Anyway, this notification routine is very small, and is written in assembler.
  840. >Here it is in its entirety:
  841. >
  842. >    move.l    4(sp), a0
  843. >    _NMRemove
  844. >    move.l    NMRec.nmRefCon(a0), a0
  845. >    _DisposePtr
  846. >    move.l    (sp)+, (sp)
  847. >    rts
  848. >
  849. >Note that the DisposePtr call is disposing of the block containing the code
  850.  
  851. I'm interested in this problem too. My notification routine looks exactly
  852. the same way. It works perfectly, but I'm concerned that it might break in
  853. the future.
  854.  
  855. Apple has warned against this sort of thing; once the block is freed, you
  856. can't make any assumptions about its contents (so you can't execute code in
  857. it). This makes sense; in a preemptive multitasking system, the block could
  858. very well by allocated by another process before you have time to rts out of
  859. it.
  860.  
  861. However, I don't see any other way of disposing properly of the Notification
  862. Record. If you want your notification to appear after your normal code is
  863. dead (INITs need to do that), then you must copy the response proc into a
  864. standalone block in the System heap. And if you want to clean up properly,
  865. you should release this block after it's been used. So there appears to be
  866. no way to do the Right Thing here.
  867.  
  868. I'd be interested in comments...
  869.  
  870.  
  871.  
  872.  
  873. -- 
  874. Francois Pottier                                            pottier@dmi.ens.fr
  875. - ----------------------------------------------------------------------------
  876. Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...
  877.  
  878. +++++++++++++++++++++++++++
  879.  
  880. >From Jaeger@fquest.com (Brian Stern)
  881. Date: 16 Sep 1994 15:48:28 GMT
  882. Organization: The University of Texas at Austin, Austin, Texas
  883.  
  884. In article <35bvgs$h87@nef.ens.fr>, pottier@fregate.ens.fr (Francois
  885. Pottier) wrote:
  886.  
  887.  
  888. < However, I don't see any other way of disposing properly of the Notification
  889. < Record. If you want your notification to appear after your normal code is
  890. < dead (INITs need to do that), then you must copy the response proc into a
  891. < standalone block in the System heap. And if you want to clean up properly,
  892. < you should release this block after it's been used. So there appears to be
  893. < no way to do the Right Thing here.
  894. < I'd be interested in comments...
  895. < -- 
  896. < Francois Pottier                                            pottier@dmi.ens.fr
  897. < ------------------------------------------------------------------------------
  898. < Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...
  899.  
  900. If you check out Dair Grant's Init Shell package, at an ftp site near you,
  901. you'll find some code that gets around this problem.  It works by poking
  902. several instructions into ToolScratch, including the disposePtr, and then
  903. jumping to those instructions.  I believe this is based on some code that
  904. was in the old usenet mac programmers guide.
  905.  
  906. Cheers,
  907.  
  908. -- 
  909. Brian  Stern  :-{)}
  910. Jaeger@fquest.com
  911.  
  912. +++++++++++++++++++++++++++
  913.  
  914. >From resnick@uiuc.edu (Pete Resnick)
  915. Date: Fri, 16 Sep 1994 15:00:26 -0500
  916. Organization: University of Illinois at Urbana-Champaign
  917.  
  918. In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  919. (Lawrence D'Oliveiro, Waikato University) wrote:
  920.  
  921. > Anyway, this notification routine is very small, and is written in assembler.
  922. > Here it is in its entirety:
  923. >         move.l  4(sp), a0
  924. >         _NMRemove
  925. >         move.l  NMRec.nmRefCon(a0), a0
  926. >         _DisposePtr
  927. >         move.l  (sp)+, (sp)
  928. >         rts
  929. > Note that the DisposePtr call is disposing of the block containing the code
  930. > (and the notification record) itself! However, I have stepped through this
  931. > code with MacsBug, and watched it successfully return from DisposePtr and
  932. > execute those last two instructions just fine.
  933.  
  934. Yow!! This would be bad since you can't depend on when that memory is
  935. going to be overwritten, and for you, it's happening in the call to
  936. _DisposePtr. There are two ways around this:
  937.  
  938. On anything better than a 68010 (which is all Macs except for the classic
  939. one) there is a wonderful little instruction: RTD. That instruction
  940. returns, but also simultaneously deallocates space on the stack. So, what
  941. I do is call _NMRemove (and whatever other cleanup I want to do) and then
  942. move the _DisposePtr and an RTD instruction to the stack:
  943.  
  944.         move.l  4(sp),a0                ; Move the NMRec
  945.         _NMRemove                       ; Remove it
  946.         move.l  NMRec.nmRefCon(a0),a1   ; Address of code+NMRec into A1
  947.         movea.l (sp)+,a0                ; Return address into A0
  948.         move.l  #$4E740006,-(sp)        ; RTD #$0006
  949.         move.w  #$a01f,-(sp)            ; _DisposePtr
  950.         move.l  a0,-(sp)                ; Return address back onto stack
  951.         pea     4(sp)                   ; Address of _DisposePtr on stack
  952.         moveq   #$1,d0
  953.         _HWPriv                         ; Flush the cache
  954.         movea.l a1,a0                   ; Address to dispose
  955.         rts                             ; Return to _DisposePtr on stack
  956.  
  957. So the stack (before the final RTS) looks like:
  958.  
  959.         +0000   <sp + 8>
  960.         +0004   <old return address>
  961.         +0008   _DisposePtr
  962.         +000A   RTD #$0006
  963.         .....Rest of stack
  964.  
  965. So when that last RTS executes, it rips the address of sp+8 off of the
  966. stack and jumps to it. The _DisposePtr disposes what's in A0 (the code and
  967. the NMRec), then the RTD takes the old return address off the stack, moves
  968. the stack pointer 6 bytes (past the _DisposePtr and the RTD #$0006), and
  969. jumps to the return address. Frightening, eh?
  970.  
  971. On the old 68000, you don't have the RTD instruction (nor an instruction
  972. cache), but life is generally a good deal simpler: There is a low memory
  973. global called "ToolScratch", which is an 8-byte scratch area. It stays
  974. constant across the call to _DisposePtr, so what you can do instead is:
  975.  
  976.         move.l  4(sp),a1                ; Move the NMRec
  977.         move.l  (sp)+,(sp)              ; Move the return address into place
  978.         _NMRemove                       ; Remove it
  979.         move.l  NMRec.nmRefCon(a1),a0   ; Address of code+NMRec into A0
  980.         movea.w #ToolScratch,a1         ; Address of the LM global
  981.         move.l  a1,-(sp)                ; Put the address onto the stack
  982.         move.l  #$a01f4E75,(a1)         ; _DisposePtr / RTS
  983.         rts
  984.  
  985. So now the stack looks like:
  986.  
  987.         +0000   <address of ToolScratch>
  988.         +0004   <old return address>
  989.         .....Rest of stack
  990.  
  991. And ToolScratch has in it:
  992.  
  993.         _DisposePtr
  994.         RTS
  995.  
  996. This has worked perfectly for me. Executing code on the stack is pretty
  997. wierd, but it works just great.
  998.  
  999. pr
  1000. -- 
  1001. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  1002. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  1003. System manager - Cognitive Science Group, Beckman Institute, UIUC
  1004. Internet: resnick@uiuc.edu
  1005.  
  1006. +++++++++++++++++++++++++++
  1007.  
  1008. >From jberry@teleport.com (James D. Berry)
  1009. Date: Fri, 16 Sep 1994 13:39:16 -0700
  1010. Organization: Consultant
  1011.  
  1012. In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  1013. (Lawrence D'Oliveiro, Waikato University) wrote:
  1014.  
  1015. > Anyway, this notification routine is very small, and is written in assembler.
  1016. > Here it is in its entirety:
  1017. >         move.l  4(sp), a0
  1018. >         _NMRemove
  1019. >         move.l  NMRec.nmRefCon(a0), a0
  1020. >         _DisposePtr
  1021. >         move.l  (sp)+, (sp)
  1022. >         rts
  1023. > Note that the DisposePtr call is disposing of the block containing the code
  1024. > (and the notification record) itself! However, I have stepped through this
  1025. > code with MacsBug, and watched it successfully return from DisposePtr and
  1026. > execute those last two instructions just fine.
  1027.  
  1028. I can't see the rest of your code, but it strikes me that if for some
  1029. reason the NMRemove call is being passed an incorrect value, then you'd be
  1030. leaving a bogus link in the NMQueue (because you've deleted the code it's
  1031. pointing to) which would cause a crash on the next invokation.
  1032.  
  1033. I'm a purest at heart, and also don't like the fact that you're executing
  1034. two instructions out of a block that's been disposed. The Modern Memory
  1035. Manager, in fact, has a debug mode that'll trash blocks as they're
  1036. disposed, which should break your code.
  1037.  
  1038. I use the following code to (cleanly?) cleanup following a notification.
  1039. Note that it assumes the NMRec and supporting code are all allocated into
  1040. a single heap block. It hasn't yet (!!) managed to break the 68K emulator,
  1041. though it seems a good target to :-()  Now if Apple would just give us a
  1042. few NM flags that specify a block to be deleted following notification!
  1043.  
  1044. ;------------------------------------------------------------
  1045. ;  pascal void NotifyProc(NMRecPtr pRec)
  1046. ;
  1047. ;  The notify proc. Its sole purpose in life is to
  1048. ;  clean-up following the notification manager.
  1049. ;------------------------------------------------------------
  1050. NotifyProc        proc
  1051.                machine  mc68020
  1052.                entry NotifyProcLen
  1053.  
  1054.                subq     #2,sp                ; Extra space 8 bytes --> 10 bytes
  1055.                move.l   2(sp),-(sp)          ; Move Return address
  1056.                move.l   10(sp),-(sp)         ; Move NMRecPtr
  1057.                
  1058.                lea      @StackCodeEnd,a1     ; Move our _DisposePtr code
  1059. onto stack
  1060.                lea      14(sp),a0            ; so that we can suicide cleanly!
  1061.                move.l   -(a1),-(a0)          ; rtd #x
  1062.                move.w   -(a1),-(a0)          ; _DisposePtr
  1063.                moveq    #6,d0                ; Length of the code
  1064.                move.l   d0,a1                ; into a1
  1065.                
  1066.                _FlushCodeCacheRange          ; Flush the caches where we
  1067. wrote code
  1068.                
  1069.                move.l   a0,a1                ; Pointer to our cleanup code
  1070. on stack
  1071.                move.l   (sp)+,a0             ; Get NMRecPtr
  1072.                
  1073.                _NMRemove                     ; Unqueue the NMRec
  1074.                
  1075.                jmp      (a1)                 ; Call cleanup code to
  1076. dispose the block we're
  1077.                                              ; currently executing out of
  1078.                                           
  1079.                ;  This code will be moved onto the stack
  1080.                ;  before it is executed, so that we don't
  1081.                ;  execute code out of a deallocated block
  1082.                
  1083.                _DisposePtr                   ; Dispose the
  1084. NMRec/code/string block
  1085.                rtd      #6                   ; Return to caller,
  1086. deallocating this code!
  1087. @StackCodeEnd
  1088.  
  1089. NotifyProcLen  dc.l  *-NotifyProc            ; Length of our notification proc
  1090.  
  1091.                endp
  1092.  
  1093. -- 
  1094. James Berry
  1095. jberry@teleport.com
  1096.  
  1097. +++++++++++++++++++++++++++
  1098.  
  1099. >From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
  1100. Date: Sat, 17 Sep 1994 14:50:34 +1200 (NZST)
  1101. Organization: (none)
  1102.  
  1103. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  1104. > I'm working on this MPW tool that sends a PostScript stream to a printer via
  1105. > PAP, and displays whatever the printer sends back.
  1106.  
  1107. Heh.  I turned your downloader XCMDs into an MPW Tool only about -- what? --
  1108. seven years ago.
  1109.  
  1110.  
  1111. > It loads the PDEF 10 code
  1112. > from the LaserWriter driver (I know, I know, but this is for in-house use
  1113. > and I have ways of keeping it working under QuickDraw GX ;-)).
  1114.  
  1115. Hmm.  Looks as if I'm going to need an update :-(
  1116.  
  1117.  
  1118. > I finally narrowed it down to one thing: the DisposePtr call in the
  1119. > notification routine, above. If I no-op out the dispose call (causing a
  1120. > resultant accumulation of allocated memory blocks in MPW's heap), I can run the
  1121. > tool multiple times just fine.
  1122. > Anybody got any ideas as to why this can't work?
  1123.  
  1124. It's not going to like the Modern Memory Manager, which stores some info
  1125. inside your data block as soon as you dispose it.
  1126.  
  1127. OTOH, if the last two instructions are surviving then it's hard to see what's
  1128. going wrong.  You *are* allocating a new block and a new copy of the code
  1129. each time you use it, right?
  1130.  
  1131. Might you not be better to allocate a small block the first time you run
  1132. and just leave it alive?  And use Gestalt or something to find it each time?
  1133.  
  1134. -- Bruce
  1135.  
  1136. +++++++++++++++++++++++++++
  1137.  
  1138. >From ludis@netcom.com (Ludis Langens)
  1139. Date: Sat, 17 Sep 1994 23:28:18 GMT
  1140. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  1141.  
  1142. In article <35bvgs$h87@nef.ens.fr> pottier@fregate.ens.fr (Francois Pottier) writes:
  1143. >In article <1994Sep16.163509.33240@waikato.ac.nz>,
  1144. >Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
  1145. >>
  1146. >>Anyway, this notification routine is very small, and is written in assembler.
  1147. >>Here it is in its entirety:
  1148. >>
  1149. >>    move.l    4(sp), a0
  1150. >>    _NMRemove
  1151. >>    move.l    NMRec.nmRefCon(a0), a0
  1152. >>    _DisposePtr
  1153. >>    move.l    (sp)+, (sp)
  1154. >>    rts
  1155. >>
  1156. >>Note that the DisposePtr call is disposing of the block containing the code
  1157. >
  1158. >I'm interested in this problem too. My notification routine looks exactly
  1159. >the same way. It works perfectly, but I'm concerned that it might break in
  1160. >the future.
  1161. >
  1162. >Apple has warned against this sort of thing; once the block is freed, you
  1163. >can't make any assumptions about its contents (so you can't execute code in
  1164. >it). This makes sense; in a preemptive multitasking system, the block could
  1165. >very well by allocated by another process before you have time to rts out of
  1166. >it.
  1167. >
  1168. >However, I don't see any other way of disposing properly of the Notification
  1169. >Record. If you want your notification to appear after your normal code is
  1170. >dead (INITs need to do that), then you must copy the response proc into a
  1171. >standalone block in the System heap. And if you want to clean up properly,
  1172. >you should release this block after it's been used. So there appears to be
  1173. >no way to do the Right Thing here.
  1174.  
  1175. To dispose the memory block out of which you are executing, try this:
  1176.  
  1177. BlockStart EQU *
  1178.  
  1179.         ...
  1180.         MOVEQ   #$1F,D0           ;Trap number of DisposPtr
  1181.         _GetTrapAddress OS
  1182.         MOVE.L  A0,A1
  1183.         LEA     BlockStart(PC),A0
  1184.         JMP     (A1)
  1185.  
  1186. Use this code as the very last thing you execute.  Make sure you have
  1187. removed any parameters from the stack (so that an RTS can return to
  1188. your caller.)  The JMP (A1) goes to the memory manager directly,
  1189. bypassing the trap dispatcher.  This means that registers D0-D2/A0-A1
  1190. may be changed.  Once DisposPtr has freed the block, it will return
  1191. (directly) to your caller.  When you link your code fragment, make sure
  1192. that BlockStart is at offset 0 in the memory block.  This same trick
  1193. can be also be used with handles by adding a RecoverHandle (and getting
  1194. the address of DisposHandle.)
  1195.  
  1196. Ludis Langens
  1197. ludis@netcom.com
  1198.  
  1199. +++++++++++++++++++++++++++
  1200.  
  1201. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  1202. Date: 19 Sep 94 14:24:01 +1200
  1203. Organization: University of Waikato, Hamilton, New Zealand
  1204.  
  1205. In article <jberry-1609941339160001@ip-ce.teleport.com>, jberry@teleport.com (James D. Berry) writes:
  1206. > In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  1207. > (Lawrence D'Oliveiro, Waikato University) wrote:
  1208. >
  1209. >> Anyway, this notification routine is very small, and is written in assembler.
  1210. >> Here it is in its entirety:
  1211. >>
  1212. >>         move.l  4(sp), a0
  1213. >>         _NMRemove
  1214. >>         move.l  NMRec.nmRefCon(a0), a0
  1215. >>         _DisposePtr
  1216. >>         move.l  (sp)+, (sp)
  1217. >>         rts
  1218. >>
  1219. >> Note that the DisposePtr call is disposing of the block containing the code
  1220. >> (and the notification record) itself! However, I have stepped through this
  1221. >> code with MacsBug, and watched it successfully return from DisposePtr and
  1222. >> execute those last two instructions just fine.
  1223. >
  1224. > I can't see the rest of your code, but it strikes me that if for some
  1225. > reason the NMRemove call is being passed an incorrect value, then you'd be
  1226. > leaving a bogus link in the NMQueue (because you've deleted the code it's
  1227. > pointing to) which would cause a crash on the next invokation.
  1228.  
  1229. The NMRec address must be correct, because its nmRefCon contains the pointer
  1230. to the entire block, which is indeed being correctly disposed. (Like I said,
  1231. I checked this with MacsBug.)
  1232.  
  1233. > I'm a purest at heart, and also don't like the fact that you're executing
  1234. > two instructions out of a block that's been disposed. The Modern Memory
  1235. > Manager, in fact, has a debug mode that'll trash blocks as they're
  1236. > disposed, which should break your code.
  1237.  
  1238. That must be the only memory manager in the world that does that...
  1239.  
  1240. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  1241. Info & Tech Services Division              fax: +64-7-838-4066
  1242. University of Waikato            electric mail: ldo@waikato.ac.nz
  1243. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  1244. "Icons are the droppings located at the top and sides of the Windows display."
  1245.                        -- reported in PC Magazine
  1246.  
  1247. +++++++++++++++++++++++++++
  1248.  
  1249. >From jan3@po.cwru.edu (James A. Nauer)
  1250. Date: Mon, 19 Sep 1994 17:18:49 -0400
  1251. Organization: Case Western Reserve University
  1252.  
  1253. In article <1994Sep19.142402.33297@waikato.ac.nz>, ldo@waikato.ac.nz
  1254. (Lawrence D'Oliveiro, Waikato University) wrote:
  1255.  
  1256. > In article <jberry-1609941339160001@ip-ce.teleport.com>,
  1257. jberry@teleport.com (James D. Berry) writes:
  1258. > >
  1259. > > I'm a purest at heart, and also don't like the fact that you're executing
  1260. > > two instructions out of a block that's been disposed. The Modern Memory
  1261. > > Manager, in fact, has a debug mode that'll trash blocks as they're
  1262. > > disposed, which should break your code.
  1263. > That must be the only memory manager in the world that does that...
  1264.  
  1265. Not true.  I have an anti-virus TSR on my PC which, among other things,
  1266. patches the (feeble) DOS memory management routines to zero out all freed
  1267. blocks before returning.  Naturally, I also have a couple of programs that
  1268. fail because they think they can get away with using a few bytes of data
  1269. in a block _after_ freeing it :-(.
  1270. -- 
  1271. James A. Nauer             | "I shall not yield one whit of maturity,
  1272. Library Information        | not grace, not respectibility, to the 
  1273. Technologies               | passing of time. I declare that I shall
  1274. Case Western Reserve Univ. | forever be, if not a child, certainly
  1275. (216) 368-MACS  (368-6227) | childish"  --Kennet Shardik
  1276.  
  1277. +++++++++++++++++++++++++++
  1278.  
  1279. >From h+@nada.kth.se (Jon W{tte)
  1280. Date: Tue, 20 Sep 1994 10:36:19 +0200
  1281. Organization: Royal Institute of Something or other
  1282.  
  1283. In article <1994Sep19.142402.33297@waikato.ac.nz>,
  1284. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote:
  1285.  
  1286. >> two instructions out of a block that's been disposed. The Modern Memory
  1287. >> Manager, in fact, has a debug mode that'll trash blocks as they're
  1288. >> disposed, which should break your code.
  1289. >
  1290. >That must be the only memory manager in the world that does that...
  1291.  
  1292. Not at all; several malloc() implementations IMMEDIATELY writes 
  1293. data into the block being disposed, like a pointer in a linked 
  1294. list of free blocks, or something like that.
  1295.  
  1296. Using a block after disposing it is BAD BAD BAD. The 
  1297. Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1298. depends on the fact that DisposePtr uses register calling 
  1299. conventions.
  1300.  
  1301. Cheers,
  1302.  
  1303.                 / h+
  1304.  
  1305.  
  1306. --
  1307.   Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  1308.  V}ga v{gra nonkonformism!
  1309.  
  1310.  
  1311. +++++++++++++++++++++++++++
  1312.  
  1313. >From fixer@faxcsl.dcrt.nih.gov (Chris Biscottimeister Tate)
  1314. Date: Tue, 20 Sep 1994 18:44:17 GMT
  1315. Organization: DCRT, NIH, Bethesda, MD
  1316.  
  1317. In article <1994Sep19.142402.33297@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  1318. >In article <jberry-1609941339160001@ip-ce.teleport.com>, jberry@teleport.com (James D. Berry) writes:
  1319. >>
  1320. >> I'm a purist at heart, and also don't like the fact that you're executing
  1321. >> two instructions out of a block that's been disposed. The Modern Memory
  1322. >> Manager, in fact, has a debug mode that'll trash blocks as they're
  1323. >> disposed, which should break your code.
  1324. >
  1325. >That must be the only memory manager in the world that does that...
  1326.  
  1327. I seem to recall running into some odd situations in which the system was
  1328. writing into unallocated heap memory for some reason.  Quickdraw, maybe?
  1329.  
  1330. (I would think that executing out of a just-deallocated block is pretty
  1331. much a recipe for disaster - certainly in a preemptive-multitasking world
  1332. you're doomed if you do it, barring some IMHO unwarranted privileges being
  1333. granted to your code...)
  1334.  
  1335. - ------------------------------------------------------------------
  1336. Christopher Tate           | "Apple Guide makes Windows' help engine
  1337. MSD, Inc.                  |  look like a quadruple amputee."
  1338. fixer@faxcsl.dcrt.nih.gov  |      -- Pete Gontier (gurgle@dnai.com)
  1339.  
  1340. +++++++++++++++++++++++++++
  1341.  
  1342. >From rang@winternet.com (Anton Rang)
  1343. Date: 21 Sep 1994 01:06:37 GMT
  1344. Organization: Trillium Research, Inc.
  1345.  
  1346. In article <9668AAA46BA3.6ED60@klkmac018.nada.kth.se> h+@nada.kth.se (Jon W{tte) writes:
  1347. >Using a block after disposing it is BAD BAD BAD. The 
  1348. >Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1349. >depends on the fact that DisposePtr uses register calling 
  1350. >conventions.
  1351.  
  1352.   Actually, you're fine with Pascal calling conventions, too, since
  1353. the callee is responsible for cleaning up the stack.  It's only if you
  1354. are trying to use C calling conventions that you'll have problems with
  1355. exiting via a call to another routine.
  1356. --
  1357. Anton Rang (rang@winternet.com)
  1358.  
  1359. +++++++++++++++++++++++++++
  1360.  
  1361. >From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
  1362. Date: Wed, 21 Sep 1994 14:48:10 +1200 (NZST)
  1363. Organization: (none)
  1364.  
  1365. resnick@uiuc.edu (Pete Resnick) writes:
  1366. > On anything better than a 68010 (which is all Macs except for the classic
  1367. > one) there is a wonderful little instruction: RTD. That instruction
  1368. > returns, but also simultaneously deallocates space on the stack. So, what
  1369. > I do is call _NMRemove (and whatever other cleanup I want to do) and then
  1370. > move the _DisposePtr and an RTD instruction to the stack:
  1371.  
  1372. Arrrrggghhh!!!
  1373.  
  1374. There are a *lot* of PowerBook 100's out there, filled to the gills with
  1375. RAM, and with a long useful life ahead of them still -- I expect to be
  1376. using mine for years yet, even though I've got a PowerMac as my main
  1377. machine.
  1378.  
  1379. In case you didn't realise, the PB100 uses an original 68000 chip.
  1380.  
  1381. -- Bruce
  1382.  
  1383. +++++++++++++++++++++++++++
  1384.  
  1385. >From ludis@netcom.com (Ludis Langens)
  1386. Date: Fri, 23 Sep 1994 21:25:04 GMT
  1387. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  1388.  
  1389. In article <9668AAA46BA3.6ED60@klkmac018.nada.kth.se> h+@nada.kth.se (Jon W{tte) writes:
  1390. >Using a block after disposing it is BAD BAD BAD. The 
  1391. >Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1392. >depends on the fact that DisposePtr uses register calling 
  1393. >conventions.
  1394.  
  1395. The Cleanup/GetTrapAddress/Jump solution does not depend upon its target
  1396. trap using register calling conventions.  A Pascal style trap can also be
  1397. called this way - just rearrange the stack appropriately.  What it does
  1398. depend upon is the register preservation and stack usage of the trap you
  1399. are chaining to.  It could not be used to chain to a C style function
  1400. or to anything that trashes registers which your function must preserve.
  1401.  
  1402. If you need to chain to a toolbox trap, the GetTrapAddress step can be
  1403. omitted by using a trap with the Auto-pop bit set.  This is a very
  1404. 'official' way of jumping to a trap.  (Years ago I used this trick
  1405. to create code segments that self UnloadSeg-ed themselves upon returning
  1406. to their caller.)
  1407.  
  1408. Ludis Langens
  1409. ludis@netcom.com
  1410.  
  1411. ---------------------------
  1412.  
  1413. >From fairgate@vespucci.iquest.com (Fairgate Technologies)
  1414. Subject: [CWWWW] PowerPlant Tour document available
  1415. Date: 23 Sep 1994 15:53:13 -0500
  1416. Organization: interQuest -- Fuel for the Mind
  1417.  
  1418. Thanks to Marc Paquette of Metrowerks, there's now a PowerPlant Tour
  1419. document on CWWWW, along with some other supporting PowerPlant
  1420. material.
  1421.  
  1422. For those of you who know what CWWWW is, these new goodies are
  1423. available on the PowerPlant Central
  1424. (http://www.iquest.com/~fairgate/cw/pplant.html) page.
  1425.  
  1426. If you haven't visited CWWWW yet, come on down! CWWWW is the official
  1427. CodeWarrior World-Wide Web site. IMNSHO there's quite a bit of useful
  1428. information there, especially for the relatively undocumented
  1429. PowerPlant class library. 
  1430.  
  1431. Point your WWW browser at http://www.iquest.com/~fairgate.
  1432.  
  1433. Cheers,
  1434. -Paul
  1435.  
  1436. [ If you don't get a reply from me with 48hrs, please resend your message.
  1437.   The Mail Gods are displeased; incoming mail is sometimes silently dropped. ]
  1438.  
  1439.  
  1440. -- 
  1441.  Paul Robichaux       Fairgate Technologies         paul@fairgate.com
  1442.       Fairgate Technologies does custom Mac development.
  1443.   Visit the CodeWarrior WWW page at http://www.iquest.com/~fairgate.
  1444.  
  1445. ---------------------------
  1446.  
  1447. End of C.S.M.P. Digest
  1448. **********************
  1449.  
  1450.  
  1451. ˇ